<?php
/** require:
 *  __PHY_LIB
 */
require_once(__PHY_LIB.'/class/Item.class.php');

class uCategory extends Item {
/// definition and constructor ///
	function uCategory($id=0, $field="") {
		Query::Query();
		$this->cfgKeyField("id");
		$this->cfgAllField("id,parent_id,rank,name,title,tree,depth");
		$this->cfgTable("unit_category");
		if ("" == $field || "*" == $field) {
			$this->cfgField($this->mAllField);
		}
		else {
			$this->cfgField($field);
		}
		if (0 < $id) {
			$this->cfgWhere($this->mKeyField . "=" . $id);
			$this->load();
		}
		else {
			$this->set($this->mKeyField, $id);
		}
	}

	function invalid() {
		if (!$this->get('title')) {
			return 'title';
		}

		return false;
	}

	function calcUrl() {
		return false; //?
	}
	function calcNewRank() {
		$sQ = "SELECT MAX(rank) max_rank FROM unit_category WHERE parent_id='".(int)$this->get('parent_id')."'";
		$this->loadQuery($sQ);
		$r = $this->nextRecord(false);
		return (int)$r['max_rank'] + 1;
	}
	function calcTree() {
		$sTree = '';
		$oOne = $this;
		while (0 < $oOne->getID()) {
			$sTree = 'R'.str_pad($oOne->get('rank'), 3, '0', STR_PAD_LEFT)
				. 'I'.str_pad($oOne->getID(), 4, '0', STR_PAD_LEFT)
				. ','.$sTree;
			$oOne = new uCategory($oOne->get('parent_id'), 'id,parent_id,rank');
		}
		$sTree = substr($sTree, 0, -1);
		return $sTree;
	}
	function calcDepth() {
		$nDepth = 0;
		$oOne = $this;
		while (0 < $oOne->getID()) {
			$nDepth++;
			$oOne = new uCategory($oOne->get('parent_id'), 'id,parent_id');
		}
		return $nDepth;
	}
	function fetchBreadCrumb() {
		if (!$this->get('tree')) { return false; }
		$rBreadCrumb = array();
		foreach (explode(',', $this->get('tree')) as $sNode) {
			$nID = (int)substr($sNode, strpos($sNode, 'I') + 1);
			$oOne = new uCategory($nID);
			if (0 < $oOne->getID()) {
				$oOne->set('link', $oOne->calcUrl());
				$rBreadCrumb[] = $oOne->getData();
			}
		}
		return $rBreadCrumb;
	}
	function rankTo($nRank) {
		if (!(0 < $this->getID())) { return false; }
		$nRank = max(1, (int)$nRank);
		$rIDs = array();
		if ($nRank > $this->get('rank')) { // 增大
			$oList = new uCategoryList();
			$oList->cfgWhere("parent_id='".$this->get('parent_id')."' AND rank>'".$this->get('rank')."' AND rank<='{$nRank}'");
			$oList->load();
			while ($o = $oList->nextItem()) {
				$rIDs[] = $o->getID();
				$o->set('rank', $o->get('rank') - 1); // 中间的统统-1
				$o->set('tree', $o->calcTree());
				$o->set('depth', $o->calcDepth());
				$o->update();
			}
		}
		elseif ($nRank < $this->get('rank')) { // 减小
			$oList = new uCategoryList();
			$oList->cfgWhere("parent_id='".$this->get('parent_id')."' AND rank<'".$this->get('rank')."' AND rank>='{$nRank}'");
			$oList->load();
			while ($o = $oList->nextItem()) {
				$rIDs[] = $o->getID();
				$o->set('rank', $o->get('rank') + 1); // 中间的统统+1
				$o->set('tree', $o->calcTree());
				$o->set('depth', $o->calcDepth());
				$o->update();
			}
		}
		else { // 相等，没变动
			return true;
		}
		/// 修改自己 ///
		$this->set('rank', $nRank);
		$this->set('tree', $this->calcTree());
		$this->set('depth', $this->calcDepth());
		$this->update();
		$rIDs[] = $this->getID();
		/// 修改影响到的子目录 ///
		if (0 < sizeof($rIDs)) {
			uCategory::refreshChildrenByParents($rIDs);
		}
		return true;
	}
	function refreshChildrenByParents($rIDs) {
		if (!is_array($rIDs)) { $rIDs = array($rIDs); }
		$oList = new uCategoryList();
		$oList->cfgWhere("parent_id IN (".implode(',', $rIDs).")");
		$oList->load();
		$rIDs = array();
		while ($o = $oList->nextItem()) {
			$rIDs[] = $o->getID();
			$o->set('tree', $o->calcTree());
			$o->set('depth', $o->calcDepth());
			$o->update();
		}
		if (0 < sizeof($rIDs)) {
			uCategory::refreshChildrenByParents($rIDs);
		}
	}
	function countChildrenByParents($rIDs) {
		if (!is_array($rIDs)) { $rIDs = array($rIDs); }
		$oList = new uCategoryList();
		$oList->cfgField("id");
		$oList->cfgWhere("parent_id IN (".implode(',', $rIDs).")");
		$oList->load();
		$nCount = 0;
		$rIDs = array();
		while ($o = $oList->nextItem()) {
			$nCount++;
			$rIDs[] = $o->getID();
		}
		if (0 < sizeof($rIDs)) {
			$nCount += uCategory::countChildrenByParents($rIDs);
		}
		return $nCount;
	}
	function getTreeIdsByTop($rIDs) {
		if (!is_array($rIDs)) { $rIDs = array($rIDs); }
		$oList = new uCategoryList();
		$oList->cfgField("id");
		$oList->cfgWhere("parent_id IN (".implode(',', $rIDs).")");
		$oList->load();
		$rMoreIDs = array();
		while ($o = $oList->nextItem()) {
			$rMoreIDs[] = $o->getID();
		}
		if (0 < sizeof($rMoreIDs)) {
			$rMoreIDs = array_merge($rMoreIDs, uCategory::getTreeIdsByTop($rMoreIDs));
		}
		return array_merge($rIDs, $rMoreIDs);
	}

} /// end class uCategory.


class uCategoryList extends ItemList {
	/// definition and constructor ///
	function uCategoryList($tablename=null) {
		ItemList::ItemList();
		$this->cfgClass("uCategory");
		$this->cfgKeyField("id");
		$this->cfgAllField("id,parent_id,rank,name,title,tree,depth");
		$this->cfgTable(null == $tablename ? "unit_category" : $tablename);
	}

} /// end class uCategoryList.
?>
